using System;
using System.Linq;
using System.Net.Http.Headers;
using Sustainalytics.Entities;
using Sustainalytics.ESGRatings.DataContract.Governance;
using Xunit;
using Xunit.Abstractions;
using Sustainalytics.ESGComputing.Service.Tests.GovernanceUnitTests.Fixtures;

namespace Sustainalytics.ESGComputing.Service.Tests.GovernanceUnitTests
{
    public class GovernanceMappingTests:Disposable, IClassFixture<GovernanceDataFromDbFixture>
    {


        private readonly ITestOutputHelper _output;
        private readonly GovernanceDataFromDbFixture _dataFixture; 
        private readonly GovernanceRatingsDto _result;
     

        public GovernanceMappingTests(GovernanceDataFromDbFixture dataFixture, ITestOutputHelper output)
        {
            _dataFixture = dataFixture;
            _output = output;
            var sutClient = new GovernanceHttpClient();
            sutClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            try
            {
                _result = sutClient.GetComputationResult(_dataFixture.SetId, _dataFixture.MatrixId);

                _output.WriteLine(_result.Dump(20));


            }
            catch (Exception e)
            {
                _output.WriteLine(e.Message, e.StackTrace);
            }

        }

        [Theory
       , InlineData(PerformanceType.Region)
       , InlineData(PerformanceType.PeerGroup)]

        public void Computation_returns_for_issue0_as_first_issue_on_benchmarks(PerformanceType type)
        {

            var rankingOutPut = _result.CompanyRating.SelectMany(x => x.CompanyBenchmarks,
                (c, b) => new
                {
                    c.CompanyId
                    ,
                    IssueBenchmarksDto = b.Value.Benchmarks[0]
                    ,
                    BenchMarkType = b.Key.ToString()
                });

            _output.WriteLine(rankingOutPut.Dump());

            Assert.True (rankingOutPut.All(x=>string.Equals(x.IssueBenchmarksDto.Issue,"CG.0",StringComparison.InvariantCultureIgnoreCase)));
           
        }


        [Fact]
        public void Computation_returns_two_benchmarks()
        {
            Assert.True(
            _result.CompanyRating.All(x => x.CompanyBenchmarks.Count == 2));
        }
   

    }


    public class GovernanceRankingTests : Disposable, IClassFixture<GovernanceDataFromDbFixture>
    {
        private readonly ITestOutputHelper _output;
        private readonly GovernanceDataFromDbFixture _dataFixture;
        private readonly GovernanceHttpClient _sutClient;

        public GovernanceRankingTests(GovernanceDataFromDbFixture dataFixture, ITestOutputHelper output)
        {
            _dataFixture = dataFixture;
            _output = output;
            _sutClient = new GovernanceHttpClient();
            _sutClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        }

        private GovernanceRatingsDto CallComputation()
        {
            try
            {
                GovernanceRatingsDto computeResult = _sutClient.GetComputationResult(_dataFixture.SetId, _dataFixture.MatrixId);

                _output.WriteLine(computeResult.Dump(20));
                
                return computeResult;
            }
            catch (Exception e)
            {
                _output.WriteLine(e.Message,e.StackTrace);
            }
            return null;
        }

        [Fact]
        public void GovernanceController_Post_ReturnsComputationResult()
        {
            var result = CallComputation();
            Assert.True(result != null);
        }

   

        [Theory
        , InlineData(PerformanceType.Region )
        , InlineData(PerformanceType.PeerGroup)]

        public void Computation_returns_for_issue0_the_number_of_companies_in_Comparative_Group(PerformanceType type)
        {
            var result = CallComputation();

            var rankingOutPut = result.CompanyRating.SelectMany(x => x.CompanyBenchmarks,
                (c, b) => new
                {
                    c.CompanyId
                    ,
                    IssueBenchmarksDto = b.Value.Benchmarks[0]
                    ,
                    BenchMarkType = b.Key.ToString()
                });

            _output.WriteLine(rankingOutPut.Dump());



            var expected = _dataFixture.GetCompaniesCountInComparativeGroup(type).OrderBy(x=>x.Item1);

            _output.WriteLine(expected.Dump());

            var actual = result.CompanyRating
                         .Select(x => 
                             new Tuple<Guid,int>(x.CompanyId,
                             x.CompanyBenchmarks[type].Benchmarks[0].IssueBenchmark.Count)).OrderBy(x=>x.Item1);



            Assert.Equal(expected, actual);
            

        }


       
        ~GovernanceRankingTests()
        {
            Dispose(false);
        }
    }
}